package com.cdbkj.cloud.pos;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.dawn.cloud.pos.drive.sdk.CLSdk;
import com.dawn.cloud.pos.drive.utils.CoderUtils;
import com.orhanobut.logger.Logger;

import cn.koolcloud.jni.ContactlessEvent;
import cn.koolcloud.jni.ContactlessInterface;

public class ClCardTest extends Activity implements OnClickListener {
	private static final String LOG_TAG = "ClCardTest";

	private static Integer[] arraySectorId = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
			10, 11, 12, 13, 14, 15 };
	private static Integer[] arrayBlockId = { 0, 1, 2, 3 };

	private ArrayAdapter<Integer> adapterSector = null;
	private ArrayAdapter<Integer> adapterBlock = null;
	private Spinner spSectorId, spBlockId = null;
	private int iSectorId = 0;
	private int iBlockId = 0;
	private TextView tvText;
	private Button btnSearchBegin, btnSearchStop, btnVerify, btnWriteMifare,
			btnReadMifare, btnOpen, btnClose, btnAPDUtrans;
	private Button btnClear;
	private EditText etKeyA, etKeyB, etWriteData, etReadData;
	private CheckBox cbKeyA, cbKeyB;
	private boolean bOpenFlag = false;
	private static final int sectorIndex = 1;
	private static final int blockIndex = 0;
	private TextView tvCardEvent;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.cl_card_test);

		btnOpen = (Button) findViewById(R.id.btnContactlessOpen);
		btnClose = (Button) findViewById(R.id.btnContactlessClose);
		btnSearchBegin = (Button) findViewById(R.id.btnSearchBegin);
		btnSearchStop = (Button) findViewById(R.id.btnSearchStop);
		btnVerify = (Button) findViewById(R.id.btnVerify);
		btnWriteMifare = (Button) findViewById(R.id.btnWriteMifare);
		btnReadMifare = (Button) findViewById(R.id.btnReadMifare);
		btnClear = (Button) findViewById(R.id.btnClear);
        btnAPDUtrans = (Button) findViewById(R.id.btnAPDUtrans);

		adapterSector = new ArrayAdapter<Integer>(this,
				android.R.layout.simple_spinner_item, arraySectorId);
		adapterSector
				.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

		adapterBlock = new ArrayAdapter<Integer>(this,
				android.R.layout.simple_spinner_item, arrayBlockId);
		adapterBlock
				.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

		// Spinners Sector
		spSectorId = (Spinner) findViewById(R.id.spSectorId);
		spSectorId.setAdapter(adapterSector);
		spSectorId.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {
				iSectorId = arraySectorId[arg2];
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
			}
		});

		// Spinners Block
		spBlockId = (Spinner) findViewById(R.id.spBlockId);
		spBlockId.setAdapter(adapterBlock);
		spBlockId.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {
				iBlockId = arrayBlockId[arg2];
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
			}
		});

		cbKeyA = (CheckBox) findViewById(R.id.cbKeyA);
		cbKeyB = (CheckBox) findViewById(R.id.cbKeyB);

		tvText = (TextView) findViewById(R.id.tvLog);
		etKeyA = (EditText) findViewById(R.id.etKeyA);
		etKeyB = (EditText) findViewById(R.id.etKeyB);
		etKeyA.setText("FFFFFFFFFFFF");
		etKeyB.setText("FFFFFFFFFFFF");

		etWriteData = (EditText) findViewById(R.id.etWriteMifare);
		etWriteData.setText("12345678123456781234567812345678");
		etReadData = (EditText) findViewById(R.id.etReadMifare);

		btnOpen.setOnClickListener(this);
		btnClose.setOnClickListener(this);
		btnSearchBegin.setOnClickListener(this);
		btnSearchStop.setOnClickListener(this);
		btnVerify.setOnClickListener(this);
		btnWriteMifare.setOnClickListener(this);
		btnReadMifare.setOnClickListener(this);
		btnClear.setOnClickListener(this);
        btnAPDUtrans.setOnClickListener(this);

		tvCardEvent = (TextView) findViewById(R.id.tvCardEventMifare);
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.btnContactlessOpen:
			openContactlessCard();
			break;

		case R.id.btnContactlessClose:
			closeContactlessCard();
			break;

		case R.id.btnSearchBegin:
			searchTargetBegin();
			break;

		case R.id.btnSearchStop:
			searchTargetStop();
			break;

		case R.id.btnVerify:
			//verifyCard();
			break;

		case R.id.btnWriteMifare:
		//	writeMifare();
			break;

		case R.id.btnReadMifare:
			readMifare();
			break;

		case R.id.btnClear:
			clear();
			break;
        case R.id.btnAPDUtrans:
			verifyAPDUtrans();
			break;
		}
	}

	private void clear() {
		tvCardEvent.setText("");
		tvText.setText("");
	}

	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {

			if (msg.arg1 == 2) {
				tvText.append("\n\t\t " + msg.obj);
				return;
			}
			Logger.i("APP", "get thread result ....\n");
			Bundle bundle = msg.getData();
			int nEventID = bundle.getInt("nEventID");
			int nEventDataLength = bundle.getInt("nEventDataLength");
			byte arryEventData[] = bundle.getByteArray("arryEventData");
			if (nEventID == 0 && nEventDataLength > 0) {
				String strDisplay = new String();
				for (int i = 0; i < nEventDataLength; i++)
					strDisplay += String.format("%02X", arryEventData[i]);
				tvText.append("\n\t\t寻卡成功！" + strDisplay);

				tvCardEvent.setText("Mifare卡Attach");
				Toast.makeText(getApplicationContext(), "寻卡成功！",
						Toast.LENGTH_SHORT).show();
			} else if (nEventID == 2) {
				Toast.makeText(getApplicationContext(), "寻卡失败！",
						Toast.LENGTH_SHORT).show();
			}
		}
	};

	/**
	 * open contactless card
	 */
	private void openContactlessCard() {
		int ret = CLSdk.open();
		if (ret < 0) {
			Logger.i(LOG_TAG, "contactless card open failed");
			Toast.makeText(getApplicationContext(), "非接触式读卡器打开失败！",
					Toast.LENGTH_SHORT).show();
			bOpenFlag = false;
		} else {
			Toast.makeText(getApplicationContext(), "非接触式读卡器打开成功！",
					Toast.LENGTH_SHORT).show();
			bOpenFlag = true;
			Logger.i(LOG_TAG, "contactless card open succ");
		}
	}

	/**
	 * close contactless card
	 */
	private void closeContactlessCard() {
		isRunning = false;
		thread = null;
		int ret = CLSdk.close();

//		ContactlessInterface.cancelPoll();
//
//		int ret = ContactlessInterface.close();
		if (ret < 0) {
			Toast.makeText(getApplicationContext(), "非接触式读卡器关闭失败！",
					Toast.LENGTH_SHORT).show();
			Logger.i(LOG_TAG, "contactless card close failed");
		} else {
			Toast.makeText(getApplicationContext(), "非接触式读卡器关闭成功！",
					Toast.LENGTH_SHORT).show();
			Logger.i(LOG_TAG, "contactless card close succ");
		}
	}

	/**
	 * search target begin
	 */
	private Thread thread = null;
	private boolean isRunning = false;
	private String cardNo = "";

	private void searchTargetBegin() {
		tvText.setText("");
		if (!bOpenFlag)
			return;

		int ret = CLSdk.searchTargetBegin();
		if (ret >= 0) {
			Logger.i(LOG_TAG, "searchTargetBegin() success");
		} else {
			Logger.i(LOG_TAG, "searchTargetBegin() fail");
		}
	}

	/**
	 * search target stop
	 */
	private void searchTargetStop() {
		if (!bOpenFlag)
			return;

		CLSdk.searchTargetEnd();
	}

	/**
	 * verify card
	 */
//	private void verifyCard() {
//		if (!bOpenFlag)
//			return;
//
//	//	boolean res = verifyPinMemory();
//		if (!res) {
//			Toast.makeText(getApplicationContext(), "验证失败！", Toast.LENGTH_SHORT)
//					.show();
//		} else {
//			Toast.makeText(getApplicationContext(), "验证成功！", Toast.LENGTH_SHORT)
//					.show();
//		}
//	}

	/**
	 * write data into mifare card
	 */
//	private void writeMifare() {
//		if (!bOpenFlag)
//			return;
//
//		String strWriteMifare = etWriteData.getText().toString().trim();
//
//		if (strWriteMifare == null || strWriteMifare.equals("")) {
//			Toast.makeText(getApplicationContext(), "请输入要写的数据！",
//					Toast.LENGTH_SHORT).show();
//			return;
//		}
//
//		byte[] bWriteMifare = Utility.Str2Bcd(strWriteMifare);
//
//		Logger.i(LOG_TAG, "====iSectorId : " + iSectorId + "==iBlockId : "
//				+ iBlockId);
//		if (!write(iSectorId, iBlockId, bWriteMifare)) {
//			Toast.makeText(getApplicationContext(), "写数据失败！",
//					Toast.LENGTH_SHORT).show();
//		} else {
//			Toast.makeText(getApplicationContext(), "写数据成功！",
//					Toast.LENGTH_SHORT).show();
//		}
//	}

	/**
	 * read data from the mifare card
	 */
	private void readMifare() {

		String strReadMifare = CLSdk.readCardSerialNo();
		if (strReadMifare!=null && !"".equals(strReadMifare)) {
			Toast.makeText(getApplicationContext(), "读数据成功！",Toast.LENGTH_SHORT).show();
			etReadData.setText(strReadMifare);
		} else {
			Toast.makeText(getApplicationContext(), "读数据失败！",Toast.LENGTH_SHORT).show();
			return;
		}
//		if (!bOpenFlag)
//			return;
//		Map map = CLSdk.readMifare(iSectorId, iBlockId);
//		int ret = (int) map.get(Constants.MAP_KEY_CODE);
//		if (ret>=0) {
//			String strReadMifare = (String) map.get(Constants.MAP_KEY_DATA);
//			Toast.makeText(getApplicationContext(), "读数据成功！",
//					Toast.LENGTH_SHORT).show();
//			etReadData.setText(strReadMifare);
//		} else {
//			Toast.makeText(getApplicationContext(), "读数据失败！",
//					Toast.LENGTH_SHORT).show();
//			return;
//		}
	}

    private void verifyAPDUtrans() {
        byte[] apduCmd0= new byte[]{0x00,(byte)0xa4,0x04,0x00,0x07,(byte)0xa0,0x00,0x00,0x03,0x33,0x01,0x01};
        byte[] apduCmd1= new byte[]{0x00,(byte)0x84,0x00,0x00,0x08};    //预期返回： 8字节随机数和2字节状态码9000
        byte[] apduCmd2= new byte[]{0x04,(byte)0x84,0x00,0x00,0x08};    //预期返回： 2字节状态码6e00表示CLA不支持或错误
        byte[] apduCmd3= new byte[]{0x00,(byte)0x84,0x00,0x00,0x01};    //预期返回： 2字节状态码6cxx表示长度错误
        byte[] response = new byte[255];
        int nResult = -1;
        switch(iSectorId)
        {
        case 0:
            nResult = ContactlessInterface.transmit(apduCmd0, apduCmd0.length, response);
            break;
        case 1:
            nResult = ContactlessInterface.transmit(apduCmd1, apduCmd1.length, response);
            break;
        case 2:
            nResult = ContactlessInterface.transmit(apduCmd2, apduCmd2.length, response);
            break;
        case 3:
            nResult = ContactlessInterface.transmit(apduCmd3, apduCmd3.length, response);
            break;
        default:
            Toast.makeText(getApplicationContext(), "sectorID(APDU测试中代表指令序号)不能大于3，即仅内置4个测试APDU指令",
		    Toast.LENGTH_SHORT).show();  
            return;         

        }

        if(nResult>=0)
        {   
            tvText.setText("");
            Toast.makeText(getApplicationContext(), "APDU指令执行成功！",
					Toast.LENGTH_SHORT).show();
            String strDisplay = new String();
				for (int i = 0; i < nResult; i++)
					strDisplay += String.format("%02X ", response[i]);
				tvText.append("APDU指令执行成功! 回应数据：" + strDisplay);
        }else{
            Toast.makeText(getApplicationContext(), "APDU指令执行失败！",
					Toast.LENGTH_SHORT).show(); 
        }       
 
	}

	/**
	 * 
	 * @param event
	 */
	private void NotifyEvent(ContactlessEvent event) {
		Message msg = new Message();
		Bundle bundle = new Bundle();
		bundle.putInt("nEventID", event.nEventID);
		bundle.putInt("nEventDataLength", event.nEventDataLength);
		bundle.putByteArray("arryEventData", event.arryEventData);
		msg.setData(bundle);
		Logger.e(LOG_TAG, "发送信息 ： ");
		handler.sendMessage(msg);
	}

	/**
	 * 
	 * @param str
	 */
	private void NotifyMessage(String str) {
		Message msg = new Message();
		msg.arg1 = 2;
		msg.obj = str;
		handler.sendMessage(msg);
	}

	/**
	 * 
	 * @param arryEventData
	 */
//	public void testVerify(byte arryEventData[]) {
//		boolean isMiFare = false;
//		// 0x08 : Type A, 0x18 : Type B
//		if (arryEventData[0] == 0x08 || arryEventData[0] == 0x18) {
//			isMiFare = true;
//		}
//		if (isMiFare) {
//	//		boolean isSuccess = verifyPinMemory();
//
//			if (isSuccess) {
//				tvText.append("\n\t\t验证密码成功！");
//				String str = read(sectorIndex, blockIndex);
//				tvText.append("\n\t\t读取数据1： " + str);
//				byte[] bytes = new byte[] { 0x00, (byte) 0x01, 0x03, 0x03,
//						(byte) 0x04 };
//				tvText.append("\n\t\t写入数据： 0x00, 0x01, 0x02, 0x03, 0x04");
//				write(sectorIndex, blockIndex, bytes);
//				String str2 = read(sectorIndex, blockIndex);
//				tvText.append("\n\t\t读取数据2： " + str2);
//			} else {
//				tvText.append("\n\t\t验证密码失败！");
//			}
//		}
//	}

	/**
	 * verify pin memory
	 * 
	 * @return
	 */
//	private boolean verifyPinMemory() {
//		boolean isSuccess = false;
//		Logger.i(LOG_TAG, "==============iSectorId: " + iSectorId);
//
//		if (cbKeyA.isChecked()) {
//			String strKeyA = etKeyA.getText().toString().trim();
//			if (strKeyA == null || strKeyA.equals("")) {
//				Toast.makeText(getApplicationContext(), "请输入KeyA",
//						Toast.LENGTH_SHORT).show();
//				return false;
//			}
//		//	byte[] bKeyA = Utility.Str2Bcd(strKeyA);
//
//			int result = ContactlessInterface.verifyPinMifare(iSectorId, 0,
//					bKeyA, bKeyA.length);
//
//			Log.d(LOG_TAG, "virify [" + "][" + "]result =" + result
//					+ ", bytes.length = " + bKeyA.length);
//			if (result >= 0) {
//				isSuccess = true;
//			}
//		}
//
//		if (cbKeyB.isChecked()) {
//			String strKeyB = etKeyB.getText().toString().trim();
//			if (strKeyB == null || strKeyB.equals("")) {
//				Toast.makeText(getApplicationContext(), "请输入KeyB",
//						Toast.LENGTH_SHORT).show();
//				return false;
//			}
//			byte[] bKeyB = Utility.Str2Bcd(strKeyB);
//
//			int result = ContactlessInterface.verifyPinMifare(iSectorId, 1,
//					bKeyB, bKeyB.length);
//
//			Log.d(LOG_TAG, "virify [" + "][" + "]result =" + result
//					+ ", bytes.length = " + bKeyB.length);
//			if (result >= 0) {
//				isSuccess = true;
//			}
//		}
//		return isSuccess;
//	}

	/**
	 * 
	 */
	private void getAttach() {
		byte arryATR[] = new byte[255];
		int nResult = ContactlessInterface.attachTarget(arryATR);
		Logger.i(LOG_TAG, "" + nResult);
		if (nResult >= 0) {
			String strDisplay = new String();
			for (int i = 0; i < nResult; i++)
				strDisplay += String.format("%02X ", arryATR[i]);
			strDisplay = "\n\t\tAttach 成功:" + strDisplay;
			NotifyMessage(strDisplay);

		} else {
			NotifyMessage("\n\t\tATTACH 发生错误，当前卡片可能不支持:" + nResult);
		}
	}

	/**
	 * 
	 * @param sectorIndex
	 * @param blockIndex
	 * @return
	 */
	private String read(int sectorIndex, int blockIndex) {
		byte[] pDataBuffer = new byte[16];
		int result = ContactlessInterface.readMifare(sectorIndex, blockIndex,
				pDataBuffer, pDataBuffer.length);
		String temp = null;
		if (result >= 0) {
//			String strInfo = StringEnCodeTools.byte2String(pDataBuffer);
//			if(strInfo != null || !"".equals(strInfo)) {
//				String strlen = strInfo.substring(0, 4);
//				int len = Integer.parseInt(strlen, 16);
//				if(len == 0) {
//					temp = strInfo.substring(4, 8);
//				} else {
//					temp = strInfo.substring(4, len * 2 + 4);
//				}
//			}
			temp = CoderUtils.ascii2String(pDataBuffer);
			for (byte b : pDataBuffer) {
				temp = temp + " " + b;
			}

			temp = getFormatString(pDataBuffer);
		}
		Logger.i(LOG_TAG, "ReadMemory " + temp + ", result = " + result);
		return temp;
	}

	/**
	 * 
	 * @param sectorIndex
	 * @param blockIndex
	 * @param str
	 * @return
	 */
	private boolean write(int sectorIndex, int blockIndex, byte[] str) {
		boolean isSuccess = false;
		byte[] bytes = str;
		int result = ContactlessInterface.writeMifare(sectorIndex, blockIndex,
				bytes, bytes.length);
		Logger.d(LOG_TAG, "write result = " + result);
		if (result >= 0) {
			isSuccess = true;
			Logger.i(LOG_TAG, "write succ");
		} else {
			Logger.i(LOG_TAG, "write fail");
		}

		return isSuccess;
	}

	/**
	 * 
	 */
	public void attachItem() {
		if (!bOpenFlag)
			return;
		getAttach();
	}

	/**
	 * 
	 * @param bytes
	 * @return
	 */
	private String getFormatString(byte[] bytes) {
		String value = "";
		for (byte b : bytes) {
			value += String.format("%02X ", b);
		}
		return value;
	}
}
